import string
from typing import Any


class StrParser:
    """
    字符串模板解析器
    
    @description 提供字符串模板的解析和格式化功能
    @class StrParser 可作为其他解析器的基类
    """

    def __init__(
        self,
        template: str = '',
        **format_field,  # 使用**接收任意数量的关键字参数
    ):
        """
        初始化解析器实例
        
        @param {str} template - 模板字符串，例如："Hello {name}"
        @param {dict} format_field - 模板变量的键值对，例如：name="World"
        @throws {ValueError} 当模板字段未提供对应值时抛出异常
        """
        # 解析模板中的字段名
        # string.Formatter().parse() 返回一个生成器，每个元素是一个元组：
        # (literal_text, field_name, format_spec, conversion)
        # 这里我们只需要field_name(索引1)，即{}中的变量名
        fields = {
            item[1]  # 获取字段名
            for item in string.Formatter().parse(template)  # 解析模板
            if item[1] is not None  # 过滤掉非占位符部分
        }
        
        # 检查是否所有模板字段都有对应的值
        # issubset()方法检查fields集合是否是format_field.keys()的子集
        if not fields.issubset(format_field.keys()):
            # 如果有字段未提供值，抛出异常
            # fields - format_field.keys() 计算缺少的字段集合
            raise ValueError(
                'not all required fields of "template" are provided, missing '
                f'{fields - format_field.keys()}. Please pass them as keyword arguments.'
            )
        
        # 保存模板和格式化字段
        self.template = template
        self.format_field = format_field

    def format_instruction(self) -> Any:
        """
        执行模板格式化
        
        @description 将所有字段值转换为字符串并填充到模板中
        @return {Any} 格式化后的字符串
        """
        # 将所有字段值转换为字符串
        format_data = {
            key: self.format_to_string(value)  # 调用转换方法
            for key, value in self.format_field.items()  # 遍历所有字段
        }
        # 使用format方法填充模板
        return self.template.format(**format_data)

    def format_to_string(self, format_model: Any) -> str:
        """
        将值转换为字符串
        
        @description 基础的字符串转换方法，子类可重写以实现特定转换逻辑
        @param {Any} format_model - 需要转换的值
        @return {str} 转换后的字符串
        """
        # 基础实现直接返回原值
        return format_model

    def format_response(self, parsed: dict) -> str:
        """
        格式化响应数据
        
        @description 抽象方法，需要子类实现具体的响应格式化逻辑
        @param {dict} parsed - 解析后的数据字典
        @return {str} 格式化后的响应字符串
        @throws {NotImplementedError} 基类中该方法未实现
        """
        raise NotImplementedError

    def parse_response(self, data: str) -> str:
        """
        解析响应数据
        
        @description 基础的响应解析方法，子类可重写以实现特定解析逻辑
        @param {str} data - 原始响应数据
        @return {str} 解析后的数据
        """
        # 基础实现直接返回原始数据
        return data
